package Test;
import java.util.Scanner;
public class Main2{
    static class Complex{
        double real,imag;
        Complex(double r,double i) {real = r;imag = i;}
        Complex add(Complex b) {return new Complex(this.real + b.real,this.imag + b.imag);}
        Complex sub(Complex b) {return new Complex(this.real - b.real,this.imag - b.imag);}
        Complex mul(Complex b){
            return new Complex(this.real * b.real - this.imag * b.imag,this.real * b.imag + this.imag * b.real);
        }
        Complex div(double d){return  new Complex(this.real / d,this.imag / d);}
    }
    static void fft(Complex[] a,boolean invert){
        int n = a.length;
        if(n == 1) return;
        Complex[] a0 = new Complex[n / 2];
        Complex[] a1 = new Complex[n / 2];
        for(int i = 0;2 * i < n;i++){
            a0[i] = a[2 * i];
            a1[i] = a[2 * i + 1];
        }
        fft(a0,invert);
        fft(a1,invert);
        double ang = 2 * Math.PI / n * (invert ? -1 : 1);
        Complex w = new Complex(1,0);
        Complex wn = new Complex(Math.cos(ang),Math.sin(ang));
        for(int i = 0;2 * i < n;i++){
            a[i] = a0[i].add(w.mul(a1[i]));
            a[i + n / 2] = a0[i].sub(w.mul(a1[i]));
            if(invert){
                a[i] = a[i].div(2);
                a[i + n / 2] = a[i + n / 2].div(2);
            }
            w = w.mul(wn);
        }
    }
    static void fftAlong(Complex[][][] tensor,boolean invert){
        int k = tensor.length;
        int i = tensor[0].length;
        int j = tensor[0][0].length;

        for(int ii = 0;ii < i;ii++)
        {
            for(int jj = 0;jj<j;jj++){
                Complex[] slice = new Complex[k];
                for(int kk = 0;kk < k;kk++){
                    slice[kk] = tensor[kk][ii][jj];
                }
                fft(slice,invert);
                for(int kk = 0;kk < k;kk++){
                    tensor[kk][ii][jj] = slice[kk];
                }
            }
        }
    }
    static Complex[][][] tprod(Complex[][][] A,Complex[][][] B){
        int ka = A.length;
        int ia = A[0].length;
        int ja = A[0][0].length;
        int kb = B.length;
        int jb = B[0].length;
        int cb = B[0][0].length;
        if(ja != jb || ka != kb){
            throw new IllegalArgumentException("维度不匹配");
        }
        fftAlong(A,false);
        fftAlong(B,false);
        int k = ka;
        int i = ia;
        int j = cb;
        Complex[][][] C = new Complex[k][i][j];
        for(int kk = 0;kk < k;kk++)
        {
            Complex[][] aSlice = A[kk];
            Complex[][] bSlice = B[kk];
            Complex[][] cSlice = new Complex[i][j];
            for(int ii = 0;ii<i;ii++)
            {
                for(int jj = 0;jj<j;jj++)
                {
                    Complex sum = new Complex(0,0);
                    for(int mm = 0;mm < ja;mm++)
                    {
                        sum = sum.add(aSlice[ii][mm].mul(bSlice[mm][jj]));
                    }
                    cSlice[ii][jj] = sum;
                }
            }
            C[kk] = cSlice;
        }
        fftAlong(C,true);
        return C;
    }
    static Complex[][][] readTensor(Scanner sc,int k,int i,int j){
        Complex[][][] tensor = new Complex[k][i][j];
        for(int kk = 0;kk < k;kk++){
            for(int ii = 0;ii < i;ii++){
                for(int jj = 0;jj < j;jj++){
                    tensor[kk][ii][jj] = new Complex(sc.nextDouble(),0);
                }
            }
        }
        return tensor;
    }
    static void printTensor(Complex[][][] tensor){
        int k = tensor.length;
        int i = tensor[0].length;
        int j = tensor[0][0].length;
        for(int kk = 0;kk < k;kk++){
            System.out.println("The " + kk + "th slice is:");
            for(int ii = 0;ii<i;ii++){
                for(int jj = 0;jj < j;jj++)
                {
                    System.out.print(Math.round(tensor[kk][ii][jj].real) + " ");
                }
                System.out.println();
            }
        }
    }
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the dimensions for tensor A (rows,columns,layers):");
        int ia = sc.nextInt();
        int ja = sc.nextInt();
        int ka = sc.nextInt();
        System.out.println("Enter the dimensions for tensor B (rows,columns,layers):");
        int jb = sc.nextInt();
        int cb = sc.nextInt();
        int kb = sc.nextInt();
        System.out.println("Enter the elements for tensor A:");
        Complex[][][] A = readTensor(sc,ka,ia,ja);
        System.out.println("Enter the elements for tensor B:");
        Complex[][][] B = readTensor(sc,kb,jb,cb);
        Complex[][][] C = tprod(A,B);
        printTensor(C);
    }
}